﻿using ExDUIR.NET.Control;
using ExDUIR.NET.Declaration;
using ExDUIR.NET.Handle;
using ExDUIR.NET.Skin;
using static ExDUIR.NET.Const.ExConst;

namespace ExDUIR
{
    public class ExBaseLayout : IBase
    {
        public readonly ExLayoutHandle _handle;

        public int Handle => _handle.Handle;
        public bool IsValid => _handle.IsInvalid;

        internal ExBaseLayout(ExLayoutHandle handle)
        {
            _handle = handle;
        }

        internal ExBaseLayout(int nType, ExControl objBind)
        {
            _handle = new ExLayoutHandle(ExAPI._layout_create(nType, objBind.Handle));
        }

        internal ExBaseLayout(int nType, ExSkin objBind)
        {
            _handle = new ExLayoutHandle(ExAPI._layout_create(nType, objBind.Handle));
        }

        /// <summary>
        /// 置内间距_左
        /// </summary>
        public int PaddingLeft
        {
            set
            {
                this.SetProp(LAYOUT_PROP_PADDING_LEFT, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_PADDING_LEFT);
            }
        }

        /// <summary>
        /// 置内间距_右
        /// </summary>
        public int PaddingRight
        {
            set
            {
                this.SetProp(LAYOUT_PROP_PADDING_RIGHT, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_PADDING_RIGHT);
            }
        }

        /// <summary>
        /// 置内间距_上
        /// </summary>
        public int PaddingTop
        {
            set
            {
                this.SetProp(LAYOUT_PROP_PADDING_TOP, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_PADDING_TOP);
            }
        }

        /// <summary>
        /// 置内间距_下
        /// </summary>
        public int PaddingBottom
        {
            set
            {
                this.SetProp(LAYOUT_PROP_PADDING_BOTTOM, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_PADDING_BOTTOM);
            }
        }

        /// <summary>
        /// 置子组件外间距_左
        /// </summary>
        public bool SetMarginLeft(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_MARGIN_LEFT, (IntPtr)value);

        /// <summary>
        /// 取子组件外间距_左
        /// </summary>
        public bool GetMarginLeft(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_MARGIN_LEFT, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置子组件外间距_上
        /// </summary>
        public bool SetMarginTop(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_MARGIN_TOP, (IntPtr)value);

        /// <summary>
        /// 取子组件外间距_上
        /// </summary>
        public bool GetMarginTop(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_MARGIN_TOP, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置子组件外间距_右
        /// </summary>
        public bool SetMarginRight(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_MARGIN_RIGHT, (IntPtr)value);

        /// <summary>
        /// 取子组件外间距_右
        /// </summary>
        public bool GetMarginRight(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_MARGIN_RIGHT, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置子组件外间距_底
        /// </summary>
        public bool SetMarginBottom(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_MARGIN_BOTTOM, (IntPtr)value);

        /// <summary>
        /// 取子组件外间距_底
        /// </summary>
        public bool GetMarginBottom(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_MARGIN_BOTTOM, out var value);
            retValue = (int)value;
            return ret;
        }

        public bool AddChild(ExControl obj) => ExAPI._layout_addchild(_handle.Handle, obj.Handle);

        public bool AddChildren(bool fDesc, int dwObjClassAtom, out int nCount) => ExAPI._layout_addchildren(_handle.Handle, fDesc, dwObjClassAtom, out nCount);

        public bool DeleteChild(ExControl obj) => ExAPI._layout_deletechild(_handle.Handle, obj.Handle);

        public bool DeleteChildren(int dwObjClassATOM) => ExAPI._layout_deletechildren(_handle.Handle, dwObjClassATOM);

        public bool SetChildProp(ExControl obj, int dwPropID, IntPtr pvValue) => ExAPI._layout_setchildprop(_handle.Handle, obj.Handle, dwPropID, pvValue);

        public bool SetProp(int dwPropID, IntPtr pvValue) => ExAPI._layout_setprop(_handle.Handle, dwPropID, pvValue);

        public bool Update() => ExAPI._layout_update(_handle.Handle);

        public bool EnableUpdate
        {
            set
            {
                ExAPI._layout_enableupdate(_handle.Handle, value);
            }
        }

        public bool GetChildProp(ExControl obj, int dwPropID, out IntPtr pvValue) => ExAPI._layout_getchildprop(_handle.Handle, obj.Handle, dwPropID, out pvValue);

        public bool GetChildPropList(ExControl obj, out IntPtr lpProps) => ExAPI._layout_getchildproplist(_handle.Handle, obj.Handle, out lpProps);

        public IntPtr GetProp(int dwPropID) => ExAPI._layout_getprop(_handle.Handle, dwPropID);

        public IntPtr GetPropList() => ExAPI._layout_getproplist(_handle.Handle);

        public int Type
        {
            get
            {
                return ExAPI._layout_gettype(_handle.Handle);
            }
        }

        public IntPtr Notify(int nEvent, IntPtr wParam, IntPtr lParam) => ExAPI._layout_notify(_handle.Handle, nEvent, wParam, lParam);

        public void Dispose() => _handle.Dispose();
    }

    public class ExAbsoluteLayout : ExBaseLayout
    {
        public ExAbsoluteLayout(ExControl objBind)
            : base(LAYOUT_TYPE_ABSOLUTE, objBind)
        {
        }

        public ExAbsoluteLayout(ExSkin objBind)
            : base(LAYOUT_TYPE_ABSOLUTE, objBind)
        {
        }

        public ExAbsoluteLayout(ExLayoutHandle hLayout)
            : base(hLayout)
        {
        }

        /// <summary>
        /// 锁定组件位置
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="tLeft">LAYOUT_SUBPROP_ABSOLUTE_XXX_TYPE</param>
        /// <param name="tTop">LAYOUT_SUBPROP_ABSOLUTE_XXX_TYPE</param>
        /// <param name="tRight">LAYOUT_SUBPROP_ABSOLUTE_XXX_TYPE</param>
        /// <param name="tBottom">LAYOUT_SUBPROP_ABSOLUTE_XXX_TYPE</param>
        /// <param name="tWidth">LAYOUT_SUBPROP_ABSOLUTE_XXX_TYPE</param>
        /// <param name="tHeight">LAYOUT_SUBPROP_ABSOLUTE_XXX_TYPE</param>
        /// <returns></returns>
        public bool Lock(ExControl obj, int tLeft, int tTop, int tRight, int tBottom, int tWidth, int tHeight) => ExAPI._layout_absolute_lock(_handle.Handle, obj.Handle, tLeft, tTop, tRight, tBottom, tWidth, tHeight);

        /// <summary>
        /// 绝对布局置边界信息
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="dwEdge">LAYOUT_SUBPROP_ABSOLUTE_</param>
        /// <param name="dwType">LAYOUT_SUBPROP_ABSOLUTE_TYPE_</param>
        /// <param name="nValue"></param>
        /// <returns></returns>
        public bool SetEdge(ExControl obj, int dwEdge, int dwType, IntPtr nValue) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, dwEdge, dwType, nValue);

        /// <summary>
        /// 置左边百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetLeftPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_LEFT, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PS, (IntPtr)value); 

        /// <summary>
        /// 置左边像素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetLeftPX(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_LEFT, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PX, (IntPtr)value);

        /// <summary>
        /// 置顶边百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetTopPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_TOP, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PS, (IntPtr)value);

        /// <summary>
        /// 置顶边像素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetTopPX(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_TOP, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PX, (IntPtr)value);

        /// <summary>
        /// 置右边百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetRightPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_RIGHT, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PS, (IntPtr)value);

        /// <summary>
        /// 置右边像素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetRightPX(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_RIGHT, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PX, (IntPtr)value);

        /// <summary>
        /// 置底边百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetBottomPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_BOTTOM, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PS, (IntPtr)value);

        /// <summary>
        /// 置底边像素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetBottomPX(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_BOTTOM, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PX, (IntPtr)value);

        /// <summary>
        /// 置宽度百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetWidthPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_WIDTH, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PS, (IntPtr)value);

        /// <summary>
        /// 置宽度像素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetWidthPX(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_WIDTH, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PX, (IntPtr)value);

        /// <summary>
        /// 置高度百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetHeightPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_HEIGHT, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PS, (IntPtr)value);

        /// <summary>
        /// 置高度像素
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetHeightPX(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_HEIGHT, LAYOUT_SUBPROP_ABSOLUTE_TYPE_PX, (IntPtr)value);

        /// <summary>
        /// 置水平偏移量百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetHorizontalOffsetPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_OFFSET_H, LAYOUT_SUBPROP_ABSOLUTE_TYPE_OBJPS, (IntPtr)value);

        /// <summary>
        /// 置垂直偏移量百分比
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetVerticalOffsetPS(ExControl obj, int value) => ExAPI._layout_absolute_setedge(_handle.Handle, obj.Handle, LAYOUT_SUBPROP_ABSOLUTE_OFFSET_V, LAYOUT_SUBPROP_ABSOLUTE_TYPE_OBJPS, (IntPtr)value);
    }

    public class ExFlowLayout : ExBaseLayout
    {
        public ExFlowLayout(ExControl objBind)
            : base(LAYOUT_TYPE_FLOW, objBind)
        {
        }

        public ExFlowLayout(ExSkin objBind)
            : base(LAYOUT_TYPE_FLOW, objBind)
        {
        }

        public ExFlowLayout(ExLayoutHandle hLayout)
            : base(hLayout)
        {
        }

        /// <summary>
        /// 取置布局方向, LAYOUT_PROP_DIRECTION
        /// </summary>
        public int Direction
        {
            set
            {
                this.SetProp(LAYOUT_PROP_FLOW_DIRECTION, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_FLOW_DIRECTION);
            }
        }

        /// <summary>
        /// 置布局子属性_尺寸 [-1或未填写为组件当前尺寸]
        /// </summary>
        public bool SetSize(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_FLOW_SIZE, (IntPtr)value);

        /// <summary>
        /// 取布局子属性_尺寸
        /// </summary>
        public bool GetSize(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_FLOW_SIZE, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置布局子属性_组件强制换行
        /// </summary>
        public bool SetNewLine(ExControl obj, bool value) => this.SetChildProp(obj, LAYOUT_SUBPROP_FLOW_NEW_LINE, (IntPtr)Convert.ToInt32(value));

        /// <summary>
        /// 取布局子属性_组件强制换行
        /// </summary>
        public bool GetNewLine(ExControl obj, ref bool retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_FLOW_NEW_LINE, out var value);
            retValue = Convert.ToBoolean((int)value);
            return ret;
        }
    }

    public class ExLinearLayout : ExBaseLayout
    {
        public ExLinearLayout(ExControl objBind)
            : base(LAYOUT_TYPE_LINEAR, objBind)
        {
        }

        public ExLinearLayout(ExSkin objBind)
            : base(LAYOUT_TYPE_LINEAR, objBind)
        {
        }

        public ExLinearLayout(ExLayoutHandle hLayout)
            : base(hLayout)
        {
        }

        /// <summary>
        /// 取置布局方向, LAYOUT_PROP_DIRECTION
        /// </summary>
        public int Direction
        {
            set
            {
                this.SetProp(LAYOUT_PROP_LINEAR_DIRECTION, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_LINEAR_DIRECTION);
            }
        }

        /// <summary>
        /// 取置布局对齐方式, LAYOUT_PROP_LINEAR_DALIGN_
        /// </summary>
        public int Dalign
        {
            set
            {
                this.SetProp(LAYOUT_PROP_LINEAR_DALIGN, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_LINEAR_DALIGN);
            }
        }

        /// <summary>
        /// 置布局子属性 另外一个方向的对齐方式, LAYOUT_SUBPROP_LINEAR_ALIGN_
        /// </summary>
        public bool SetAlign(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_LINEAR_ALIGN, (IntPtr)value);

        /// <summary>
        /// 置布局子属性 另外一个方向的对齐方式, LAYOUT_SUBPROP_LINEAR_ALIGN_
        /// </summary>
        public bool GetAlign(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_LINEAR_ALIGN, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置线性布局子属性_尺寸 [-1或未填写为组件当前尺寸]
        /// </summary>
        public bool SetSize(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_LINEAR_SIZE, (IntPtr)value);

        /// <summary>
        /// 取线性布局子属性_尺寸
        /// </summary>
        public bool GetSize(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_LINEAR_SIZE, out var value);
            retValue = (int)value;
            return ret;
        }
    }

    public class ExPageLayout : ExBaseLayout
    {
        public ExPageLayout(ExControl objBind)
            : base(LAYOUT_TYPE_PAGE, objBind)
        {
        }

        public ExPageLayout(ExSkin objBind)
            : base(LAYOUT_TYPE_PAGE, objBind)
        {
        }

        public ExPageLayout(ExLayoutHandle hLayout)
            : base(hLayout)
        {
        }

        /// <summary>
        /// 当前显示页面索引
        /// </summary>
        public int Current
        {
            set
            {
                this.SetProp(LAYOUT_PROP_PAGE_CURRENT, (IntPtr)value);
            }
            get
            {
                return (int)this.GetProp(LAYOUT_PROP_PAGE_CURRENT);
            }
        }

        /// <summary>
        /// 置布局子属性_是否填充整个布局
        /// </summary>
        public bool SetFill(ExControl obj, bool value) => this.SetChildProp(obj, LAYOUT_SUBPROP_PAGE_FILL, (IntPtr)Convert.ToInt32(value));

        /// <summary>
        /// 取布局子属性_是否填充整个布局
        /// </summary>
        public bool GetFill(ExControl obj, ref bool retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_PAGE_FILL, out var value);
            retValue = Convert.ToBoolean((int)value);
            return ret;
        }
    }

    public class ExRelativateLayout : ExBaseLayout
    {
        public ExRelativateLayout(ExControl objBind)
            : base(LAYOUT_TYPE_RELATIVE, objBind)
        {
        }

        public ExRelativateLayout(ExSkin objBind)
            : base(LAYOUT_TYPE_RELATIVE, objBind)
        {
        }

        public ExRelativateLayout(ExLayoutHandle hLayout)
            : base(hLayout)
        {
        }

        /// <summary>
        /// 置相对布局子属性_左侧于(组件)
        /// </summary>
        public bool SetLeftOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_LEFT_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_左侧于(组件)
        /// </summary>
        public bool SetLeftOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_LEFT_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_左侧于(组件)
        /// </summary>
        public bool GetLeftOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_LEFT_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_之上于(组件)
        /// </summary>
        public bool SetTopOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_TOP_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_之上于(组件)
        /// </summary>
        public bool SetTopOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_TOP_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_之上于(组件)
        /// </summary>
        public bool GetTopOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_TOP_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_右侧于(组件)
        /// </summary>
        public bool SetRightOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_RIGHT_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_右侧于(组件)
        /// </summary>
        public bool SetRightOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_RIGHT_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_右侧于(组件)
        /// </summary>
        public bool GetRightOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_RIGHT_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_之下于(组件)
        /// </summary>
        public bool SetBottomOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_BOTTOM_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_之下于(组件)
        /// </summary>
        public bool SetBottomOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_BOTTOM_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_之下于(组件)
        /// </summary>
        public bool GetBottomOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_BOTTOM_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_左对齐于(组件)
        /// </summary>
        public bool SetLeftAlignOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_LEFT_ALIGN_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_左对齐于(组件)
        /// </summary>
        public bool SetLeftAlignOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_LEFT_ALIGN_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_左对齐于(组件)
        /// </summary>
        public bool GetLeftAlignOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_LEFT_ALIGN_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_顶对齐于(组件)
        /// </summary>
        public bool SetTopAlignOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_TOP_ALIGN_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_顶对齐于(组件)
        /// </summary>
        public bool SetTopAlignOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_TOP_ALIGN_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_顶对齐于(组件)
        /// </summary>
        public bool GetTopAlignOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_TOP_ALIGN_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_右对齐于(组件)
        /// </summary>
        public bool SetRightAlignOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_RIGHT_ALIGN_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_右对齐于(组件)
        /// </summary>
        public bool SetRightAlignOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_RIGHT_ALIGN_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_右对齐于(组件)
        /// </summary>
        public bool GetRightAlignOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_RIGHT_ALIGN_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置相对布局子属性_底对齐于(组件)
        /// </summary>
        public bool SetBottomAlignOf(ExControl obj, ExControl obj2) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_BOTTOM_ALIGN_OF, (IntPtr)obj2.Handle);

        /// <summary>
        /// 置相对布局子属性_底对齐于(组件)
        /// </summary>
        public bool SetBottomAlignOf(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_BOTTOM_ALIGN_OF, (IntPtr)value);

        /// <summary>
        /// 取相对布局子属性_底对齐于(组件)
        /// </summary>
        public bool GetBottomAlignOf(ExControl obj, ref ExControl retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_BOTTOM_ALIGN_OF, out var value);
            retValue = new ExControl(new ExControlHandle((int)value));
            return ret;
        }

        /// <summary>
        /// 置布局子属性_相对_水平居中于父
        /// </summary>
        public bool SetCenterParentHorizontal(ExControl obj, bool value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_CENTER_PARENT_H, (IntPtr)Convert.ToInt32(value));

        /// <summary>
        /// 取布局子属性_相对_水平居中于父
        /// </summary>
        public bool GetCenterParentHorizontal(ExControl obj, ref bool retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_CENTER_PARENT_H, out var value);
            retValue = Convert.ToBoolean((int)value);
            return ret;
        }

        /// <summary>
        /// 置布局子属性_相对_垂直居中于父
        /// </summary>
        public bool SetCenterParentVertical(ExControl obj, bool value) => this.SetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_CENTER_PARENT_V, (IntPtr)Convert.ToInt32(value));

        /// <summary>
        /// 取布局子属性_相对_垂直居中于父
        /// </summary>
        public bool GetCenterParentVertical(ExControl obj, ref bool retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_RELATIVE_CENTER_PARENT_V, out var value);
            retValue = Convert.ToBoolean((int)value);
            return ret;
        }
    }

    public class ExTableLayout : ExBaseLayout
    {
        public ExTableLayout(ExControl objBind)
            : base(LAYOUT_TYPE_TABLE, objBind)
        {
        }

        public ExTableLayout(ExSkin objBind)
            : base(LAYOUT_TYPE_TABLE, objBind)
        {
        }

        public ExTableLayout(ExLayoutHandle hLayout)
            : base(hLayout)
        {
        }

        /// <summary>
        /// 设置表格信息
        /// </summary>
        /// <param name="aRowHeight">行高数组,正数为像素,负数为百分比</param>
        /// <param name="cRows">行数</param>
        /// <param name="aCellWidth">列宽数组,正数为像素,负数为百分比</param>
        /// <param name="cCells">列数</param>
        /// <returns></returns>
        public bool SetInfo(int[] aRowHeight, int cRows, int[] aCellWidth, int cCells) => ExAPI._layout_table_setinfo(_handle.Handle, aRowHeight, cRows, aCellWidth, cCells);

        /// <summary>
        /// 置所在行
        /// </summary>
        public bool SetRow(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_TABLE_ROW, (IntPtr)value);

        /// <summary>
        /// 取所在行
        /// </summary>
        public bool GetRow(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_TABLE_ROW, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置所在列
        /// </summary>
        public bool SetCell(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_TABLE_CELL, (IntPtr)value);

        /// <summary>
        /// 取所在列
        /// </summary>
        public bool GetCell(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_TABLE_CELL, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置跨行数
        /// </summary>
        public bool SetRowSpan(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_TABLE_ROW_SPAN, (IntPtr)value);

        /// <summary>
        /// 取跨行数
        /// </summary>
        public bool GetRowSpan(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_TABLE_ROW_SPAN, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置跨列数
        /// </summary>
        public bool SetCellSpan(ExControl obj, int value) => this.SetChildProp(obj, LAYOUT_SUBPROP_TABLE_CELL_SPAN, (IntPtr)value);

        /// <summary>
        /// 取跨列数
        /// </summary>
        public bool GetCellSpan(ExControl obj, ref int retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_TABLE_CELL_SPAN, out var value);
            retValue = (int)value;
            return ret;
        }

        /// <summary>
        /// 置是否填满
        /// </summary>
        public bool SetFill(ExControl obj, bool value) => this.SetChildProp(obj, LAYOUT_SUBPROP_TABLE_FILL, (IntPtr)Convert.ToInt32(value));

        /// <summary>
        /// 取是否填满
        /// </summary>
        public bool GetFill(ExControl obj, ref bool retValue)
        {
            var ret = this.GetChildProp(obj, LAYOUT_SUBPROP_TABLE_FILL, out var value);
            retValue = Convert.ToBoolean((int)value);
            return ret;
        }
    }
}
